﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Log = Logger.Debug;

namespace Xiaowei.Services
{
    public enum eQMPHostState
    {
        eQQMPLAYER_State_Stop = 0,
        eQQMPLAYER_State_Buffer = (eQQMPLAYER_State_Stop + 1),
        eQQMPLAYER_State_Play = (eQQMPLAYER_State_Buffer + 1),
        eQQMPLAYER_State_Pause = (eQQMPLAYER_State_Play + 1),
        eQQMPLAYER_State_Begin = (eQQMPLAYER_State_Pause + 1),
        eQQMPLAYER_State_End = (eQQMPLAYER_State_Begin + 1),
        eQQMPLAYER_State_BeforPlay = (eQQMPLAYER_State_End + 1)
    };

    public enum SongType
    {
        SongType_None = -1,
        SongType_LocalSong = 0,     //本地歌曲
                                    //1和2都用dwQQSongID，0,3和4使用strURL
        SongType_QQSong = 1,        //普通QQ歌曲
        SongType_FakeUrl = 2,       //伪链歌曲
        SongType_URL = 3,       //URL歌曲
        SongType_LLQSong = 111,     //低品质库
        SongType_BellSong = 112,        //铃声库
        SongType_AccompanySong = 113,       //伴奏库
    };

    public interface IQQMusicService
    {
        event QQMusicPlayStateChangedHandler PlayStateChanged;
        void OpenQQMusic(string args);
        bool IsStarted { get; }
        bool IsInstalled { get; }
        int PlayerStatus { get; }
        string PlayerSongID { get; }
    }
    public delegate void QQMusicPlayStateChangedHandler(int State, string ID, bool IsInstalled, bool IsStarted);
    internal class QQMusicService: IQQMusicService
    {
        [DllImport("TencentSignature.dll", CharSet = CharSet.Unicode)]
        private static extern bool IsFileSignedByTencent(string s);
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindowA(string classname, string windowname);
        [DllImport("user32.dll")]
        private static extern IntPtr GetPropA(IntPtr hWnd, string lpString);
        [DllImport("user32.dll")]
        private static extern bool IsWindow(IntPtr hWnd);
        
        public event QQMusicPlayStateChangedHandler PlayStateChanged;

        public QQMusicService()
        {
            Task.Run(QuaryStateTask);
        }



        private string id = "";
        private int state = 0;
        private bool isInstalled = false;
        private bool isStarted = false;
        private async void QuaryStateTask()
        {
            while (true)
            {
                string id = PlayerSongID;
                int state = PlayerStatus;
                bool isInstalled = IsInstalled;
                bool isStarted = IsStarted;
                if (state != this.state || id != this.id || isInstalled != this.isInstalled || isStarted != this.isStarted)
                {
                    this.state = state;
                    this.id = id;
                    this.isInstalled = isInstalled;
                    this.isStarted = isStarted;
                    PlayStateChanged?.Invoke(state, id,IsInstalled,isStarted);
                }
                await Task.Delay(1000);
            }
        }

        public void OpenQQMusic(string args)
        {
            Log.WriteLine($"OpenQQMusic, args:{args}");
            string path = "";
            if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Tencent\QQMusic") != null)
            {
                path = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Tencent\QQMusic").GetValue("install").ToString();
            }
            else if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Tencent\QQMusic") != null)
            {
                path = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Tencent\QQMusic").GetValue("install").ToString();
            }
            else
            {
                Log.WriteLine($"OpenQQMusic 2, args:{args}");
                return;
            }
            Log.WriteLine($"OpenQQMusic, path:{path}, args:{args}.");
            Process.Start(path + "QQmusic.exe", args);
            Log.WriteLine($"OpenQQMusic, path:{path}, args:{args} end.");
            return;
        }

        public bool IsStarted
        {
            get
            {
                if (Process.GetProcessesByName("QQMusic").Count() == 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }

        }

        public bool IsInstalled
        {
            get
            {
                string path;
                if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Tencent\QQMusic") != null)
                {
                    path = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Tencent\QQMusic").GetValue("install").ToString() + "QQmusic.exe";
                    if (!File.Exists(path))
                    {
                        return false;
                    }
                    else if (IsFileSignedByTencent(path))
                        return true;
                    else return false;
                }
                else if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Tencent\QQMusic") != null)
                {
                    path = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Tencent\QQMusic").GetValue("install").ToString() + "QQmusic.exe";
                    if (!File.Exists(path))
                    {
                        return false;
                    }
                    else if (IsFileSignedByTencent(path))
                        return true;
                    else return false;
                }
                else
                {
                    return false;
                }
            }

        }

        public int PlayerStatus
        {
            get
            {
                IntPtr hWnd = FindWindowA("QQMusic_Daemon_Wnd", null);
                if (IsWindow(hWnd))
                {
                    return (int)GetPropA(hWnd, "Player_Status");
                }
                return 0;
            }
        }
        public string PlayerSongID
        {
            get
            {
                IntPtr hWnd = FindWindowA("QQMusic_Daemon_Wnd", null);
                if (IsWindow(hWnd))
                {
                    return ((uint)GetPropA(hWnd, "Player_SongID")).ToString();
                }
                return "";
            }
        }
    }
}
